fn main() {
    println!("Hello, world! {}", longest("Hello", "world"));

    // 编译器采用三条规则来判断引用何时不需要明确的注解。第一条规则适用于输入生命周期，后两条规则适用于输出生命周期。
    // 如果编译器检查完这三条规则后仍然存在没有计算出生命周期的引用，编译器将会停止并生成错误。
    // 这些规则适用于 fn 定义，以及 impl 块。
    //
    // 第一条规则是编译器为每一个引用参数都分配一个生命周期参数。
    // 换句话说就是，函数有一个引用参数的就有一个生命周期参数：fn foo<'a>(x: &'a i32)，
    // 有两个引用参数的函数就有两个不同的生命周期参数，
    // fn foo<'a, 'b>(x: &'a i32, y: &'b i32)，依此类推。
    //
    // 第二条规则是如果只有一个输入生命周期参数，
    // 那么将它赋予给所有输出生命周期参数：fn foo<'a>(x: &'a i32) -> &'a i32。
    //
    // 第三条规则是如果方法有多个输入生命周期参数并且其中一个参数是 &self 或 &mut self，
    // 说明这是个方法，那么所有输出生命周期参数被赋予 self 的生命周期。第三条规则使得方法更容易读写，因为只需更少的符号。
}

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}
